#include "threadPool.h"
int LS_Server(int netfd, cmdInfo_t *pcmdinfo, MYSQL *mysql) {
    printf("----------------------------------------LS_Server------------------"
           "------------");
    // 解析arg
    // arg一定为空
    char sql[4096];
    memset(sql, 0, sizeof(sql));
    printf("user_id = %d\n", pcmdinfo->user_id);
    sprintf(sql,
            "SELECT file_name FROM `virtualFile` WHERE user_id = %d AND "
            "curr_path = '%s';",
            pcmdinfo->user_id, pcmdinfo->cmdPath);
    printf("LS_Server: sql = %s\n", sql);
    MYSQL_RES *result = mysqlSearch(sql, mysql);
    if (result == NULL) {
        printf("mysql find no data\n");
    }
    MYSQL_ROW row;
    // 读取的同时，拼接字符串。最后一起发回
    char buf[4096] = {0};
    train_t train;
    memset(&train, 0, sizeof(train));
    int flag = 0;
    while (row = mysql_fetch_row(result)) {
        flag = 1;
        strcat(buf, row[0]);
        strcat(buf, "$");
        printf("buf = %s\n", buf);
    }
    if (flag == 0) {
        // 告诉客户端本次LS失败
        sendYesOrNo(netfd, "-1", sizeof("-1"));
        return -1;
    }
    // 告诉客户端本次LS成功
    sendYesOrNo(netfd, "0", sizeof("0"));
    // 把LS的结果传给客户端
    train.length = strlen(buf);
    printf("strLen = %d\n",train.length);
    memcpy(train.data, buf, train.length);
    char buf2[4096] = {0};
    memcpy(buf2, train.data, train.length);
    printf("buf2 = %s\n", buf2);
    send(netfd, &train, sizeof(int) + train.length, MSG_NOSIGNAL);
    return 0;
}
int CD_Server(int netfd, cmdInfo_t *pcmdinfo, MYSQL *mysql) {
    // 解析arg，看当前工作目录里有没有该目录，是不是目录？
    // 解析arg,解决.和..的特殊情况
    printf("----------------------------------------CD_Server------------------"
           "------------");
    char sql[4096];
    train_t train;
    memset(sql, 0, sizeof(sql));
    memset(&train, 0, sizeof(train));
    if (strcmp(pcmdinfo->arg, "..") == 0) {
        // 返回上一级目录
        // 为了处理当前文件夹为空的情况，所以要修改sql
        char pathbuf_for_select[100] = {0};
        strcpy(pathbuf_for_select, pcmdinfo->cmdPath);
        pathbuf_for_select[strlen(pathbuf_for_select) - 1] =
            '\0'; // 去掉当前路径pcmdinfo->cmdPath最右边的'/'
        sprintf(sql,
                "SELECT file_id from virtualFile WHERE path_client = '%s' and "
                "user_id = %d;",
                pathbuf_for_select, pcmdinfo->user_id);
        printf("CD ..sql = %s\n", sql);
        MYSQL_RES *result = mysqlSearch(sql, mysql);
        if (result == NULL) {
            printf("mysql find no data\n");
        }
        MYSQL_ROW row = mysql_fetch_row(result);
        if (row == NULL) {
            printf("cd..: 未找到任何数据\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        int pre_id = atoi(row[0]);
        printf("pre_id = %d\n", pre_id);
        if (pre_id == -1) {
            // 返回-1给客户端
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            printf("已经是根目录，无法返回上一级\n");
        } else {
            // 返回0给客户端
            sendYesOrNo(netfd, "0", sizeof("0"));

            // 继续发送cd ..后的工作目录
            memset(&train, 0, sizeof(train));
            char *p = pcmdinfo->cmdPath;
            p += strlen(pcmdinfo->cmdPath) - 1;
            *p = '\0';
            p--;
            while (*p != '/') {
                *p = '\0';
                printf("buf = %s\n", pcmdinfo->cmdPath);
                p--;
            }
            printf("after cd,path = %s\n", pcmdinfo->cmdPath);
            train.length = strlen(pcmdinfo->cmdPath);
            printf("train.length = %d\n", train.length);
            memcpy(train.data, pcmdinfo->cmdPath, train.length);
            char buf[4096] = {0};
            memcpy(buf, train.data, train.length);
            printf("buf = %s\n", buf);
            send(netfd, &train, sizeof(int) + train.length, MSG_NOSIGNAL);
            return 0;
        }
    } else { // 此时说明不是cd.. 而是进入下一级目录
        sprintf(sql,
                "SELECT file_name FROM `virtualFile` WHERE user_id = %d AND "
                "curr_path = '%s' AND file_type = 'd';",
                pcmdinfo->user_id, pcmdinfo->cmdPath);
        MYSQL_RES *result = mysqlSearch(sql, mysql);
        if (result == NULL) {
            printf("mysql find no data\n");
        }
        MYSQL_ROW row;
        while (row = mysql_fetch_row(result)) {
            printf("当前搜索的目录：%s\n", row[0]);
            if (strcmp(row[0], pcmdinfo->arg) == 0) {
                // 返回0给客户端
                sendYesOrNo(netfd, "0", sizeof("0"));

                // 开始拼接路径
                strcat(pcmdinfo->cmdPath, row[0]);
                strcat(pcmdinfo->cmdPath, "/");
                printf("after cd,path = %s\n", pcmdinfo->cmdPath);
                train.length = strlen(pcmdinfo->cmdPath);
                printf("train.length = %d\n", train.length);
                memcpy(train.data, pcmdinfo->cmdPath, train.length);
                char buf[4096] = {0};
                memcpy(buf, train.data, train.length);
                printf("buf = %s\n", buf);
                send(netfd, &train, sizeof(int) + train.length, MSG_NOSIGNAL);
                // 返回0给客户端
                train.length = strlen("0");
                memcpy(train.data, "0", train.length);
                char buf3[4096] = {0};
                memcpy(buf3, train.data, train.length);
                printf("buf3 = %s\n", buf3);
                printf("ret = %s\n", buf3);
                return 0;
            }
        }
        printf("未找到文件夹或参数有误!\n");
        // 返回-1给客户端
        sendYesOrNo(netfd, "-1", sizeof("-1"));
        return -1;
    }
}
int REMOVE_Server(int netfd, cmdInfo_t *pcmdinfo, MYSQL *mysql) {
    printf("--------------------from REMOVE_Server-----------------\n");
    char sql[4096];
    memset(sql, 0, sizeof(sql));
    // 先检查
    // 先检查要删除的文件/目录是否存在
    bool isRelativePath = 1; // 根据arg中是否带“/”来判断其是否为相对路径
    int fileIdToRm = 0; // 如果arg合法，保存要删除的file_id
    char *p = pcmdinfo->arg;
    printf("--------------------from REMOVE_Server-----------------\n");
    while (*p != '\0') {
        if (*p == '/') {
            isRelativePath = 0;
            break;
        }
        p++;
    }
    if (!isRelativePath) {
        // 此处说明arg为绝对路径
        // 再判断路径开头是.还是/
        char absolutePath[100] = {0};
        if (pcmdinfo->arg[0] == '.') {
            if (pcmdinfo->arg[1] == '.') {
                printf("非法输入！\n");
                sendYesOrNo(netfd, "-1", sizeof("-1"));
                return -1;
            }
            printf(".start\n");
            // 此时需要拼接出绝对路径
            strcpy(absolutePath, pcmdinfo->cmdPath);
            absolutePath[strlen(absolutePath) - 1] = '\0';
            p = strtok(pcmdinfo->arg, ".");
            strcat(absolutePath, p);
            printf("after cat,absolutePath = %s\n", absolutePath);
        } else if (pcmdinfo->arg[0] == '/') {
            printf("/start\n");
            strcpy(absolutePath, pcmdinfo->arg);
            printf("absolutePath = %s\n", absolutePath);
        } else {
            printf("Illegal path\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        // 用绝对路径查找DB
        sprintf(sql,
                "SELECT file_id FROM virtualFile WHERE path_client = '%s' AND "
                "user_id = %d;",
                absolutePath, pcmdinfo->user_id);
        printf("rm: sql = %s\n", sql);
        MYSQL_RES *result = mysqlSearch(sql, mysql);
        if (result == NULL) {
            printf("mysql find no data\n");
        }
        MYSQL_ROW row = mysql_fetch_row(result);
        if (row == NULL) {
            printf("rm: 未找到任何数据\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        fileIdToRm = atoi(row[0]); // 找到了要删除的文件的file_id;
        printf("fileIdToRm = %d\n", fileIdToRm);
        // 从DB中删除该文件

        // 从storage中在物理上删除该文件
    } else {
        char relativePath[100] = {0};
        printf("this is not a absolute path\n");
        // 用“相对路径”查找DB
        strcpy(relativePath, pcmdinfo->arg);
        sprintf(sql,
                "SELECT file_id FROM virtualFile WHERE file_name = '%s' AND "
                "user_id = %d;",
                relativePath, pcmdinfo->user_id);
        printf("rm: sql = %s\n", sql);
        MYSQL_RES *result = mysqlSearch(sql, mysql);
        if (result == NULL) {
            printf("mysql find no data\n");
        }
        MYSQL_ROW row = mysql_fetch_row(result);
        if (row == NULL) {
            printf("rm: 未找到任何数据\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        fileIdToRm = atoi(row[0]); // 找到了要删除的文件的file_id;
/*         sendYesOrNo(netfd, "0", sizeof("0")); */
    }
    // 运行到此，说明pcmdInfo->arg是合法的，下面正式开始删除DB中的数据
    memset(sql, 0, sizeof(sql));
    // 先检查是目录还是普通文件

    sprintf(sql, "SELECT file_type FROM virtualFile WHERE file_id = %d;",
            fileIdToRm);
    printf("a01\n");
    printf("rm: check d or c  sql = %s\n", sql);
    printf("a02\n");
    MYSQL_RES *result = mysqlSearch(sql, mysql);
    printf("a03\n");
    if (result == NULL) {
        printf("a01\n");
        printf("mysql find no data\n");
        printf("a01\n");
        sendYesOrNo(netfd, "-1", sizeof("-1"));
        printf("a01\n");
        return -1;
    }
    printf("a04\n");
    MYSQL_ROW row = mysql_fetch_row(result);
    printf("a05\n");
    if (row == NULL) {
        printf("a06\n");
        printf("rm: 未找到任何数据\n");
        printf("a07\n");
        sendYesOrNo(netfd, "-1", sizeof("-1"));
        return -1;
    }
    printf("a08\n");
    char *file_type = row[0];          // 找到了要删除的文件的类型;
    printf("a09\n");
    if (strcmp(file_type, "c") == 0) { // 要删除的是普通文件，直接删除
    printf("a10\n");
        memset(sql, 0, sizeof(sql));
        sprintf(sql, "DELETE FROM virtualFile WHERE file_id = %d;", fileIdToRm);
        int qret = mysql_query(mysql, sql);
        if (qret != 0) {
            fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        printf("已删除file_id = %d\n",fileIdToRm);
        sendYesOrNo(netfd, "0", sizeof("0"));
        return 0;
    } else if (strcmp(file_type, "d") == 0) { // 要删除的是目录，如果是空目录就删除。非空目录报错
        // 如果是空目录
        printf("a11\n");
        memset(sql, 0, sizeof(sql));
        printf("a12\n");
        sprintf(sql, "SELECT file_id FROM virtualFile WHERE pre_id = %d AND user_id = %d;",
                fileIdToRm, pcmdinfo->user_id);
        printf("a13\n");
        MYSQL_RES *result = mysqlSearch(sql, mysql);
        printf("a14\n");
        if (result == NULL) {
            printf("a15\n");
            printf("mysql find no data\n");
            printf("a16\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        printf("a17\n");
        MYSQL_ROW row = mysql_fetch_row(result);
        printf("a18\n");
        if (row != NULL) {
            printf("a19\n");
            printf("该目录不是空目录，不能删\n");
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        printf("a20\n");
        memset(sql, 0, sizeof(sql));
        printf("a21\n");
        sprintf(sql, "DELETE FROM virtualFile WHERE file_id = %d;", fileIdToRm);
        printf("a22\n");
        int qret = mysql_query(mysql, sql);
        if (qret != 0) {
            fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
            sendYesOrNo(netfd, "-1", sizeof("-1"));
            return -1;
        }
        printf("已删除file_id = %d\n",fileIdToRm);
        printf("a23\n");
        sendYesOrNo(netfd, "0", sizeof("0"));
        return 0;
    }
    printf("rm: unknown mistake\n");
    sendYesOrNo(netfd, "-1", sizeof("-1"));
    return -1;
    printf("REMOVE_Server\n");
}
int PWD_Server(int netfd, cmdInfo_t *pcmdinfo, MYSQL *mysql) {
    printf("PWD_Server\n");
}
int MKDIR_Server(int netfd, cmdInfo_t *pcmdinfo, MYSQL *mysql) {
    printf("--------------------from MKDIR_Server-----------------\n");
    char sql[4096];
    memset(sql, 0, sizeof(sql));
    // 先检查目录是否已存在
    sprintf(sql,
            "SELECT * FROM virtualFile WHERE user_id = %d AND curr_path = '%s' "
            "AND file_name = '%s';",
            pcmdinfo->user_id, pcmdinfo->cmdPath, pcmdinfo->arg);
    printf("MKDIR select sql: = %s\n", sql);
    MYSQL_RES *result = mysqlSearch(sql, mysql);
    if (result == NULL) {
        printf("mysql find no data\n");
    }
    MYSQL_ROW row = mysql_fetch_row(result);
    if (row != NULL) {
        sendYesOrNo(netfd, "-1", sizeof("-1"));
        printf("Directory already exists!\n");
        return -1;
    }
    // 开始添加目录
    memset(sql, 0, sizeof(sql));
    char filePath[100] = {
        0}; // 插入的目录的文件路径名，例：D目录的文件路径名为 /B/C/D
    strcpy(filePath, pcmdinfo->cmdPath);
    strcat(filePath, pcmdinfo->arg);
    // 获取pre_id
    int pre_id = 0;
    char pathbuf_for_select[100] = {0};
    strcpy(pathbuf_for_select, pcmdinfo->cmdPath);
    pathbuf_for_select[strlen(pathbuf_for_select) - 1] =
        '\0'; // 去掉当前路径pcmdinfo->cmdPath最右边的'/'
    sprintf(sql,
            "SELECT file_id from virtualFile WHERE path_client = '%s' and "
            "user_id = %d;",
            pathbuf_for_select, pcmdinfo->user_id);
    printf("MKDIR insert sql: = %s\n", sql);
    result = mysqlSearch(sql, mysql);
    if (result == NULL) {
        printf("mysql find no data\n");
    }
    row = mysql_fetch_row(result);
    if (row == NULL) {
        pre_id = -1;
    } else {
        pre_id = atoi(row[0]);
    }
    printf("pre_id = %d\n", pre_id);

    // 执行insert
    /* printf("filePath = %s\n",filePath); */
    //--------------------------------------------------------------------------------------------目录文件的大小没写
    sprintf(sql,
            "INSERT INTO virtualFile (file_name, user_id, pre_id, path_client, "
            "file_size, file_type, file_hash, curr_path) "
            "VALUES ('%s', %d, %d, '%s', 0, 'd', 'null', '%s');",
            pcmdinfo->arg, pcmdinfo->user_id, pre_id, filePath,
            pcmdinfo->cmdPath);
    int qret = mysql_query(mysql, sql);
    if (qret != 0) {
        fprintf(stderr, "mysql_query:%s\n", mysql_error(mysql));
    }
    printf("mysqlSearch: sql = %s\n", sql);
    sendYesOrNo(netfd, "0", sizeof("0"));
    printf("LS_Server: sql = %s\n", sql);

    printf("MKDIR_Server\n");
}
int sendYesOrNo(int netfd, const char *errinfo, int errinfoLen) {
    train_t train;
    memset(&train, 0, sizeof(train));
    train.length = errinfoLen;
    memcpy(train.data, errinfo, train.length);
    char buf2[4096] = {0};
    memcpy(buf2, train.data, train.length);
    printf("buf2 = %s\n", buf2);
    printf("ret = %s\n", buf2);
    send(netfd, &train, sizeof(int) + train.length, MSG_NOSIGNAL);
}
